#include "g729a.h"

void g729a_encoder_init(struct g729a_encoder *encoder) {
    init_pre_process(&encoder->pre_proc);
    init_coder_ld8a(&encoder->ld8);
}

void g729a_encoder_proc(struct g729a_encoder *encoder, const int16_t *input_pcm, uint8_t *output_bitstream) {
    int prm[PRM_SIZE]; /* Transmitted parameters */
    int i;

    for (i = 0; i < L_FRAME; i++)
        encoder->ld8.new_speech[i] = (FLOAT) input_pcm[i];

    pre_process(&encoder->pre_proc, encoder->ld8.new_speech, L_FRAME);

    coder_ld8a(&encoder->ld8, prm);

    prm2bits_ld8k_c(prm, output_bitstream);
}

void g729a_encoder_deinit(struct g729a_encoder *encoder) {

}



void g729a_decoder_init(struct g729a_decoder *decoder) {
    int i;

    for (i = 0; i < M; i++)
        decoder->synth_buf[i] = (F) 0.0;
    decoder->synth = decoder->synth_buf + M;

    init_decod_ld8a(&decoder->ld8);
    init_post_filter(&decoder->postfilter);
    init_post_process(&decoder->postprocess);
}

void g729a_decoder_proc(struct g729a_decoder *decoder, const uint8_t *input_bitstream, int bfi, int16_t *output_pcm) {
    int parm[PRM_SIZE+2]; /* Synthesis parameters + BFI */
    FLOAT Az_dec[MP1*2]; /* Decoded Az for post-filter */
    int T2[2]; /* Decoded Pitch */

    parm[0] = bfi;

    bits2prm_ld8k_c(input_bitstream, parm + 1);

    parm[4] = check_parity_pitch(parm[3], parm[4]); /* get parity check result */

    decod_ld8a(&decoder->ld8, parm, decoder->synth, Az_dec, T2);             /* decoder */

    post_filter(&decoder->postfilter, decoder->synth, Az_dec, T2);                  /* Post-filter */

    post_process(&decoder->postprocess, decoder->synth, L_FRAME);                    /* Highpass filter */

    float2int16(output_pcm, decoder->synth);
}

void g729a_decoder_deinit(struct g729a_decoder *decoder) {

}